﻿#Region "Imports"
Imports System.DirectoryServices
#End Region

Public Class IIsVirtualDirectory
    Implements IDisposable

#Region "Privates"

    Private _VirtualDirEntry As DirectoryEntry

#End Region

#Region "Constructors and Destructors"

    Public Sub New(ByVal VirtualDirEntry As DirectoryEntry)

        If VirtualDirEntry.SchemaClassName = VirtualDirectorySchemaClassName Then

            _VirtualDirEntry = VirtualDirEntry
            _VirtualDirEntry.RefreshCache()

        Else

            ConstructorEx(VirtualDirectorySchemaClassName)

        End If

    End Sub

    Protected Overrides Sub Finalize()

        If Not _VirtualDirEntry Is Nothing Then _VirtualDirEntry.Close()

    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose

        If Not _VirtualDirEntry Is Nothing Then _VirtualDirEntry.Close()

    End Sub

#End Region

#Region "Properties"

    Public ReadOnly Property Name() As String
        Get

            Return _VirtualDirEntry.Name

        End Get
    End Property

    Public Property Path() As String
        Get

            Return GetProperty("Path", _VirtualDirEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("Path", value, _VirtualDirEntry)

        End Set
    End Property


    Public ReadOnly Property IsApplication() As Boolean
        Get

            Dim AppRoot = CStr(GetProperty("AppRoot", _VirtualDirEntry)).Replace(LocalMachineNamespace, IIsProviderPath)

            Return If(AppRoot = _VirtualDirEntry.Path, True, False)

        End Get
    End Property

    Public Property ApplicationPoolId() As String
        Get

            Return GetProperty("AppPoolId", _VirtualDirEntry)

        End Get
        Set(ByVal value As String)

            If Me.IsApplication Then

                SetProperty("AppPoolId", value, _VirtualDirEntry)

            Else

                SetPropertyEx("AppPoolId", New Exception("This is not an application. Can't set Application Pool."))

            End If

        End Set
    End Property

    Public Property ApplicationName() As String
        Get

            Return GetProperty("AppFriendlyName", _VirtualDirEntry)

        End Get
        Set(ByVal value As String)

            If Me.IsApplication Then

                SetProperty("AppFriendlyName", value, _VirtualDirEntry)

            Else

                SetPropertyEx("AppFriendlyName", New Exception("This is not an application. Can't set Application Name."))

            End If

        End Set
    End Property

    Public Property ASPNETVersion() As ASPNETVersions
        Get

            Return GetScriptMaps(_VirtualDirEntry.Path)

        End Get
        Set(ByVal value As ASPNETVersions)

            If Me.IsApplication Then

                SetScriptMaps(_VirtualDirEntry.Path, value)

            Else

                SetPropertyEx("ASPNETVersion", New Exception("This is not an application. Can't set ASP.NET Version."))

            End If

        End Set
    End Property


    Public Property DirectoryBrowsing() As DirectoryBrowseFlags
        Get

            Return GetProperty("DirBrowseFlags", _VirtualDirEntry)

        End Get
        Set(ByVal value As DirectoryBrowseFlags)

            SetProperty("DirBrowseFlags", value, _VirtualDirEntry)

        End Set
    End Property

    Public Property DefaultDocuments() As String
        Get

            Return GetProperty("DefaultDoc", _VirtualDirEntry)

        End Get
        Set(ByVal value As String)

            SetProperty("DefaultDoc", value, _VirtualDirEntry)

        End Set
    End Property

    Public Property AccessPermissions() As AccessPermissionFlags
        Get

            Return GetProperty("AccessFlags", _VirtualDirEntry)

        End Get
        Set(ByVal value As AccessPermissionFlags)

            SetProperty("AccessFlags", value, _VirtualDirEntry)

        End Set
    End Property

    Public Property AuthenticationMethods() As AuthenticationFlags
        Get

            Return GetProperty("AuthFlags", _VirtualDirEntry)

        End Get
        Set(ByVal value As AuthenticationFlags)

            SetProperty("AuthFlags", value, _VirtualDirEntry)

        End Set
    End Property


    Public ReadOnly Property Directories() As IIsDirectory()
        Get

            Dim Dirs() As IIsDirectory = {}

            Try

                Dim DirEntries = From de As DirectoryEntry In _VirtualDirEntry.Children _
                                 Where de.SchemaClassName = DirectorySchemaClassName _
                                 Select de

                For Each d In DirEntries

                    ReDim Preserve Dirs(Dirs.Length)
                    Dirs(Dirs.Length - 1) = New IIsDirectory(d)

                Next

            Catch ex As Exception

                GetPropertyEx("Directories", ex)

            End Try

            Return Dirs

        End Get
    End Property

    Public ReadOnly Property VirtualDirectories() As IIsVirtualDirectory()
        Get

            Dim VirtualDirs() As IIsVirtualDirectory = {}

            Try

                Dim VirtualDirEntries = From vde As DirectoryEntry In _VirtualDirEntry.Children _
                                        Where vde.SchemaClassName = VirtualDirectorySchemaClassName _
                                        Select vde

                For Each vd In VirtualDirEntries

                    ReDim Preserve VirtualDirs(VirtualDirs.Length)
                    VirtualDirs(VirtualDirs.Length - 1) = New IIsVirtualDirectory(vd)

                Next

            Catch ex As Exception

                GetPropertyEx("VirtualDirectories", ex)

            End Try

            Return VirtualDirs

        End Get
    End Property

    Public ReadOnly Property Files() As IIsFile()
        Get

            Dim Fs() As IIsFile = {}

            Try

                Dim FileEntries = From fe As DirectoryEntry In _VirtualDirEntry.Children _
                                  Where fe.SchemaClassName = FileSchemaClassName _
                                  Select fe

                For Each f In FileEntries

                    ReDim Preserve Fs(Fs.Length)
                    Fs(Fs.Length - 1) = New IIsFile(f)

                Next

            Catch ex As Exception

                GetPropertyEx("Files", ex)

            End Try

            Return Fs

        End Get
    End Property

#End Region

#Region "Public Functions and Methods"

    Public Function AddDirectory(ByVal Name As String) As IIsDirectory

        AddDirectory = Nothing

        Try

            Dim d As DirectoryEntry = _VirtualDirEntry.Invoke("Create", DirectorySchemaClassName, Name)

            d.CommitChanges()

            AddDirectory = New IIsDirectory(d)

            d.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add Directory '{0}'.", Name), ex)

        End Try

    End Function

    Public Function AddVirtualDirectory(ByVal Name As String, ByVal Path As String) As IIsVirtualDirectory

        AddVirtualDirectory = Nothing

        Try

            Dim vd As DirectoryEntry = _VirtualDirEntry.Invoke("Create", VirtualDirectorySchemaClassName, Name)

            vd.CommitChanges()

            AddVirtualDirectory = New IIsVirtualDirectory(vd)

            AddVirtualDirectory.Path = Path

            vd.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add Virtual Directory '{0}'.", Name), ex)

        End Try

    End Function

    Public Function AddFile(ByVal Name As String) As IIsFile

        AddFile = Nothing

        Try

            Dim f As DirectoryEntry = _VirtualDirEntry.Invoke("Create", FileSchemaClassName, Name)

            f.CommitChanges()

            AddFile = New IIsFile(f)

            f.Close()

        Catch ex As Exception

            Throw New Exception(String.Format("An error occured while trying to add File '{0}'.", Name), ex)

        End Try

    End Function

    Public Sub CreateApplication(Optional ByVal ApplicationName As String = "", Optional ByVal ApplicationPoolId As String = "")

        If Me.IsApplication Then

            Throw New Exception("This is already an application.")

        Else

            Try

                _VirtualDirEntry.Invoke("AppCreate2", 2)

                If ApplicationName <> "" Then

                    Me.ApplicationName = ApplicationName

                Else

                    Me.ApplicationName = Me.Name

                End If

                If ApplicationPoolId <> "" Then Me.ApplicationPoolId = ApplicationPoolId

            Catch ex As Exception

                Throw New Exception("An error occured while trying to create an application.", ex)

            End Try

        End If

    End Sub

    Public Sub DeleteApplication(Optional ByVal Recursive As Boolean = False)

        If Me.IsApplication Then

            Try

                If Recursive Then

                    _VirtualDirEntry.Invoke("AppDeleteRecursive")

                Else

                    _VirtualDirEntry.Invoke("AppDelete")

                End If

            Catch ex As Exception

                Throw New Exception("An error occured while trying to delete an application.", ex)

            End Try

        Else

            Throw New Exception("This is not an application.")

        End If

    End Sub

#End Region

End Class
